<?php
if (!class_exists('WP_Redis_Cache')) {
    class WP_Redis_Cache
    {
        private $redis;
        private $prefix;
        private $connected = false;
        private $default_config = [
            'host'       => '127.0.0.1',
            'port'       => 6379,
            'timeout'    => 1,
            'password'   => '',
            'database'   => 0,
            'prefix'     => 'rwps:'
        ];

        public function __construct(array $config = [])
        {
            $config = array_merge($this->default_config, $config);
            $this->prefix = $config['prefix'];

            try {
                if (extension_loaded('redis') && class_exists('Redis')) {
                    $this->redis = new \Redis();
                    $this->connected = $this->redis->connect(
                        $config['host'],
                        $config['port'],
                        $config['timeout']
                    );

                    if (!empty($config['password'])) {
                        $this->redis->auth($config['password']);
                    }

                    $this->redis->select($config['database']);

                    // Test connection
                    $this->connected = $this->redis->ping() === true;
                }
            } catch (\RedisException $e) {
                error_log('Redis connection error: ' . $e->getMessage());
                $this->connected = false;
            }
        }


        /**
         * Get cached data with optional default value
         */
        public function get($key, $default = null)
        {
            if (!$this->connected) {
                return $default;
            }

            $full_key = $this->prefix . $key;
            $data = $this->redis->get($full_key);

            return $data !== false ? unserialize($data) : $default;
        }

        /**
         * Set cache with expiration (in seconds)
         */
        public function set($key, $data, $expire = 0)
        {
            if (!$this->connected) {
                return false;
            }

            $full_key = $this->prefix . $key;
            $serialized = serialize($data);

            try {
                if ($expire > 0) {
                    return $this->redis->setex($full_key, $expire, $serialized);
                }
                return $this->redis->set($full_key, $serialized);
            } catch (\RedisException $e) {
                error_log('Redis set error: ' . $e->getMessage());
                return false;
            }
        }

        /**
         * Delete cache key
         */
        public function delete($key)
        {
            if (!$this->connected) {
                return false;
            }

            $full_key = $this->prefix . $key;
            try {
                return $this->redis->del($full_key) > 0;
            } catch (\RedisException $e) {
                error_log('Redis delete error: ' . $e->getMessage());
                return false;
            }
        }

        /**
         * Clear all cache with current prefix
         */
        public function flush()
        {
            if (!$this->connected) {
                return false;
            }

            return false;
            try {
                $keys = $this->redis->keys($this->prefix . '*');
                if (!empty($keys)) {
                    return $this->redis->del($keys) > 0;
                }
                return true;
            } catch (\RedisException $e) {
                error_log('Redis flush error: ' . $e->getMessage());
                return false;
            }
        }

        /**
         * Check if Redis is connected and responsive
         */
        public function is_connected()
        {
            if (!$this->connected) {
                return false;
            }

            try {
                return $this->redis->ping() === true;
            } catch (\RedisException $e) {
                return false;
            }
        }
        public function add_list($key, $id)
        {
            if (!$this->connected) {
                return false;
            }
            $full_key = $this->prefix . $key;
            $this->redis->rpush($full_key, $id);
            return true;
        }
        public function add_lists($key, $ids)
        {
            if (!$this->connected) {
                return false;
            }

            $full_key = $this->prefix . $key;
            if (is_string($ids)) {
                $ids = explode(",", $ids);
            }
            if (is_array($ids) && !empty($ids)) {
                foreach ($ids as $id) {
                    $this->redis->rpush($full_key, $id);
                }
            }
            return true;
        }
        public function add_zset($key, array $idScrore = [])
        {
            if (!$this->connected) {
                return false;
            }
            $full_key = $this->prefix . $key;

            if (is_array($idScrore) && !empty($idScrore)) {
                foreach ($idScrore as $id => $score) {
                    $this->redis->zadd($full_key, $score, $id);
                }
            }
            return true;
        }


        public function lrange($key, $start = 0, $end = -1)
        {
            if (!$this->connected) {
                return false;
            }
            $full_key = $this->prefix . $key;
            return $this->redis->lrange($full_key, $start, $end);
        }
        public function list_page($key, $page = 1, $per_page = 10)
        {
            if (!$this->connected) {
                return false;
            }

            $full_key = $this->prefix . $key;
            return $this->redis->lrange($full_key, ($page - 1) * $per_page, $page * $per_page - 1);
        }

        public function zset_page($key, $page = 1, $per_page = 10, $sort = SORT_DESC)
        {
            if (!$this->connected) {
                return false;
            }
            $full_key = $this->prefix . $key;

            if ($sort === SORT_DESC) {
                return $this->redis->zrevrange($full_key, ($page - 1) * $per_page, $page * $per_page - 1);
            }

            return $this->redis->zrange($full_key, ($page - 1) * $per_page, $page * $per_page - 1);
        }

        public function setHash($key, $data, $expire = 24 * 60 * 60)
        {
            if (!$this->connected) {
                return false;
            }
            $full_key = $this->prefix . $key;
            $result = $this->redis->hmset($full_key, $data);
            if ($result) {
                $this->redis->expire($full_key, $expire);
            }
            return $result;
        }

        public function getHash($key, $fields = [])
        {
            if (!$this->connected) {
                return false;
            }
            $full_key = $this->prefix . $key;

            if (empty($fields)) {
                return $this->redis->hGetAll($full_key);
            }
            return $this->redis->hMGet($full_key, $fields);
        }


        public function exists($key)
        {
            if (!$this->connected) {
                return false;
            }
            $full_key = $this->prefix . $key;
            return $this->redis->exists($full_key);
        }

        public function sadd($key, $id)
        {
            if (!$this->connected) {
                return false;
            }
            $full_key = $this->prefix . $key;
            return $this->redis->sadd($full_key, $id);
        }
        public function srandmember($key, $count)
        {
            if (!$this->connected) {
                return false;
            }
            $full_key = $this->prefix . $key;
            return $this->redis->srandmember($full_key, $count);
        }
        public function expire($key, $expire)
        {
            if (!$this->connected) {
                return false;
            }
            $full_key = $this->prefix . $key;
            return $this->redis->expire($full_key, $expire);
        }
    }

    // 全局初始化
    function init_redis()
    {
        global $wp_redis;
        if (!isset($wp_redis)) {
            $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'default';
            $hostParts = explode(".", preg_replace('/[^a-zA-Z0-9.-]/', '', $host));
            $prefix = array_shift($hostParts);

            $wp_redis = new WP_Redis_Cache(['prefix' => $prefix . ':']);
            if (!$wp_redis->is_connected()) {
                error_log('Failed to initialize Redis connection');
            }
        }
        return $wp_redis;
    }

    // 确保在 wp_loaded 之前初始化
    add_action('init', 'init_redis', 1);
}
